package cn.qinhao.pethome.login.controller;

import cn.qinhao.pethome.basic.base.BaseConstants;
import cn.qinhao.pethome.basic.exception.BusinessException;
import cn.qinhao.pethome.basic.until.AjaxResult;
import cn.qinhao.pethome.basic.until.HttpClientUtils;
import cn.qinhao.pethome.basic.until.MD5Utils;
import cn.qinhao.pethome.basic.until.StrUtils;
import cn.qinhao.pethome.login.domain.LoginVo;
import cn.qinhao.pethome.login.domain.WxToken;
import cn.qinhao.pethome.login.domain.WxVo;
import cn.qinhao.pethome.login.service.ILogininfoService;
import cn.qinhao.pethome.org.domain.User;
import cn.qinhao.pethome.org.mapper.UserMapper;
import cn.qinhao.pethome.org.service.IUserService;
import cn.qinhao.pethome.three.domain.Wxuser;
import cn.qinhao.pethome.three.mapper.WxuserMapper;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/wxlogin")
public class WxLoginController {
    @Value("${wx.appid}")
    private String appid;
    @Value("${wx.secret}")
    private String secret;
    @Autowired
    private WxuserMapper wxuserMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private IUserService userService;
    @Autowired
    private ILogininfoService logininfoService;
    @Autowired
    private  RedisTemplate redisTemplate;
    //获取用户信息
   @GetMapping("/{code}")
    public AjaxResult WxLogin(@PathVariable("code")String code){

       try {
           //1、根据地址携带参数获取令牌(code+AppID+AppSecret )
           String url= "https://api.weixin.qq.com/sns/oauth2/access_token" +
                   "?appid=APPID" +
                   "&secret=SECRET" +
                   "&code=CODE" +
                   "&grant_type=authorization_code";
           //替换参数
           url=url.replaceAll("APPID",appid).replaceAll("SECRET",secret).replaceAll("CODE",code);
           //使用工具类发送get请求
           String result = HttpClientUtils.httpGet(url);
           //转化为Json对象，就可以直接获取返回参数里面的值(根据api的返回值封装返回参数)
           WxToken wxToken = JSONObject.parseObject(result, WxToken.class);
           //2、根据返回的参   数获取用户信息(access_token+openid)
           String wxUserinfo="https://api.weixin.qq.com/sns/userinfo" +
                   "?access_token=ACCESS_TOKEN" +
                   "&openid=OPENID";
           //替换参数
           wxUserinfo=wxUserinfo.replaceAll("ACCESS_TOKEN",wxToken.getAccess_token())
              .replaceAll("OPENID",wxToken.getOpenid());
           //发送请求
           String wxinfoResult = HttpClientUtils.httpGet(wxUserinfo);
           //转换json对象，因为返回字段和数据库中的一样，所以生成微信用户代码
           Wxuser wxuser = JSONObject.parseObject(wxinfoResult, Wxuser.class);
           System.out.println(wxuser);
           //3、逻辑
           //数据库查询微信用户
           Wxuser petWxuser = wxuserMapper.loadByOpenid(wxuser.getOpenid());
           if(petWxuser==null){//没有就添加用户
               //添加用户
               wxuserMapper.add(wxuser);
                   //携带用户的唯一标识返回信息未绑定
               return AjaxResult.me().setSuccess(true).setResultObj(wxuser.getOpenid()).setMessage("NoBind");
           }
           //微信用户不是空就判断useid是否为空，为空说明没有绑定
           if(petWxuser.getUserId()==null){
               return AjaxResult.me().setSuccess(true).setResultObj(wxuser.getOpenid()).setMessage("NoBind");
           }
           //4、登录
           //不为空说明已经绑定，就直接去登录
           User user = userMapper.selectOne(petWxuser.getUserId());
           LoginVo loginVo = new LoginVo();
           loginVo.setPassword(user.getPassword());//注意：此处密码是加了密了，所以还要去加密那里做一个判断
           loginVo.setUsername(user.getUsername());
           loginVo.setType(BaseConstants.logininfo.STATE_type_user);
           loginVo.setIsThree(true);
           //调用接口登录获取taken
           String taken = logininfoService.login(loginVo);
           return AjaxResult.me().setSuccess(true).setResultObj(taken).setMessage("ok");
       } catch (Exception e) {
           e.printStackTrace();
           return AjaxResult.me().setSuccess(false).setMessage("网络繁忙");
       }
   }
   //绑定页面
    //1、获取短信验证码
   //获取短信验证码
   @PostMapping
   public AjaxResult sendSms(@RequestBody WxVo wxVo){
       try {
           //1、校验手机后不能为空
           if(wxVo.getPhone()==null){
               throw new BusinessException("手机号不能为空");
           }
           //2、1分钟后才能再次点击
           Object keycheck = redisTemplate.opsForValue().get(wxVo.getPhone() + BaseConstants.ImgCode.STATE_REGISTER_CHECK);
           if (keycheck!=null){
               throw new BusinessException("请在60秒后再获取");
           }
           //3、校验3分钟
           Object key = redisTemplate.opsForValue().get(wxVo.getPhone() + BaseConstants.ImgCode.STATE_BIND);
           if(key!=null){//不为空就发送同一个验证码
               System.out.println(key.toString());
           }
           //根据手机号查询该用户是否注册了，注册了才能绑定
           User user = userMapper.loadByPhone(wxVo.getPhone());
           if(user==null){//为空说明用户没有注册
               User newUser = new User();
               newUser.setUsername(wxVo.getPhone());
               newUser.setPhone(wxVo.getPhone());
               newUser.setState(BaseConstants.User.STATE_NORMAL);
               String salt = StrUtils.getComplexRandomString(32);
               newUser.setSalt(salt);
               newUser.setPassword(MD5Utils.encrypByMd5("666666"+salt));
               newUser.setCreatetime(new Date());
               userService.add(newUser);
               //发送短信通知对方密码，怎么去修改
           }else{//不为空则查询是否绑定,看是否有userid
            Wxuser wxuser=wxuserMapper.loadUserId(user.getId());
            if(wxuser!=null){//根据userid能查出来就说明已经绑定
                throw new BusinessException("该手机号已被绑定");
            }
                //为空代表没有绑定,生成验证码
               String randomString = StrUtils.getRandomString(4);
                //验证码存入redis，3分钟内发送同一个验证码
                redisTemplate.opsForValue().set(wxVo.getPhone()+BaseConstants.ImgCode.STATE_BIND
                        ,randomString,3,TimeUnit.MINUTES);
                //存入redis，1分钟之后才能再次点击获取
               redisTemplate.opsForValue().set(wxVo.getPhone()+BaseConstants.ImgCode.STATE_BIND_CHECK
                       ,"",1,TimeUnit.MINUTES);
                //模拟发送短信
               System.out.println(randomString);
           }
           return AjaxResult.me().setSuccess(true);
       } catch (BusinessException e) {
           return AjaxResult.me().setSuccess(false).setMessage(e.getMessage());
       }catch (Exception e) {
           e.printStackTrace();
           return AjaxResult.me().setSuccess(false).setMessage("网络繁忙");
       }
   }
    //2、做绑定
    @PostMapping("/bind")
    public AjaxResult bindWxUser(@RequestBody WxVo wxVo){
        try {
            //1、校验参数非空
            if (wxVo.getPhone() == null) {
                throw new BusinessException("手机号不能为空");
            }
            if (wxVo.getOpenid() == null) {
                throw new BusinessException("参数异常");
            }
            //2、判断验证码
            Object code = redisTemplate.opsForValue().get(wxVo.getPhone() + BaseConstants.ImgCode.STATE_BIND);
            if (code == null) {
                throw new BusinessException("验证码已经过期");
            }
            //不等于空，再判断是否相同
            if (!wxVo.getCode().equals(code)) {
                throw new BusinessException("验证码输入错误");
            }
            //给该用户做绑定，等价于设置userid和user做关联
            //获取用户user
            User user = userMapper.loadByPhone(wxVo.getPhone());
            //获取微信用户wxuser
            Wxuser wxuser = wxuserMapper.loadByOpenid(wxVo.getOpenid());
            //根据用户的id设置管理useid
            wxuser.setUserId(user.getId());
            //刷新
            wxuserMapper.update(wxuser);

            //绑定好了调用登录接口获取token，最终实现扫码后就登录
            //设置登录参数
            LoginVo loginVo = new LoginVo();
            loginVo.setUsername(user.getUsername());
            loginVo.setPassword(user.getPassword());
            loginVo.setIsThree(true);
            loginVo.setType(BaseConstants.logininfo.STATE_type_user);
            String token = logininfoService.login(loginVo);
            return AjaxResult.me().setSuccess(true).setResultObj(token);

        } catch (BusinessException e) {
            return AjaxResult.me().setSuccess(false).setMessage(e.getMessage());
        }catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.me().setSuccess(false).setMessage("网络繁忙！！");
        }
    }
}
